package com.kunlun.basedata.service.impl;

import com.kunlun.basedata.dao.IAllotAuthorizeDao;
import com.kunlun.basedata.model.AllotModel;
import com.kunlun.basedata.model.MenuModel;
import com.kunlun.basedata.model.UserModel;
import com.kunlun.basedata.model.enums.AllotTypeEnum;
import com.kunlun.basedata.model.vo.AllotAuthorizeVo;
import com.kunlun.basedata.model.vo.AuthorizeDetailVo;
import com.kunlun.basedata.service.IAllotAuthorizeService;
import com.kunlun.basedata.service.IMenuService;
import com.kunlun.basedata.service.IUserService;
import com.kunlun.basedata.utils.CommonUtil;
import com.kunlun.common.constant.CommonConstant;
import com.kunlun.common.model.Page;
import com.kunlun.common.utils.TreeUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 岗位业务Service类
 */
@Service
@Transactional
public class AllotAuthorizeService implements IAllotAuthorizeService {

    private final Logger logger = LogManager.getLogger();

    @Autowired
    private IAllotAuthorizeDao allotAuthorizeDao;

    @Autowired
    private IUserService userService;

    @Autowired
    private IMenuService menuService;

    @Override
    public Page<AllotAuthorizeVo> getAllotDepartments(AllotAuthorizeVo allotAuthorizeVo, int currentPage, int pageSize) throws Exception {
        int startIndex = (currentPage - 1) * pageSize;
        Map<String, Object> queryMap = CommonUtil.packageQueryMap(allotAuthorizeVo, startIndex, pageSize);
        int count = allotAuthorizeDao.getAllotDepartmentCount(queryMap);
        List<AllotAuthorizeVo> allotDepartments = allotAuthorizeDao.getAllotDepartments(queryMap);
        for (AllotAuthorizeVo model : allotDepartments) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(CommonConstant.DATE_FORMAT);
            Date date = dateFormat.parse(model.getOperateTime());
            model.setOperateTime(dateFormat.format(date));
        }

        Page<AllotAuthorizeVo> page = new Page<>();
        page.setCurrentPage(currentPage);
        page.setPageSize(pageSize);
        page.setTotal(count);
        page.setRecords(allotDepartments);
        return page;
    }

    @Override
    public Page<AllotAuthorizeVo> getAllotPosts(AllotAuthorizeVo allotAuthorizeVo, int currentPage, int pageSize) throws Exception {
        int startIndex = (currentPage - 1) * pageSize;
        Map<String, Object> queryMap = CommonUtil.packageQueryMap(allotAuthorizeVo, startIndex, pageSize);
        int count = allotAuthorizeDao.getAllotPostCount(queryMap);
        List<AllotAuthorizeVo> allotDepartments = allotAuthorizeDao.getAllotPosts(queryMap);
        AllotAuthorizeVo authorizeVo = allotAuthorizeDao.getAuthorizeItem(allotAuthorizeVo.getAllotId(), "3");
        for (AllotAuthorizeVo model : allotDepartments) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(CommonConstant.DATE_FORMAT);
            Date date = dateFormat.parse(model.getOperateTime());
            model.setOperateTime(dateFormat.format(date));
            model.setAuthorizeId(authorizeVo.getCorrelateId());
            model.setAuthorizeItem(authorizeVo.getCorrelateName());
        }

        Page<AllotAuthorizeVo> page = new Page<>();
        page.setCurrentPage(currentPage);
        page.setPageSize(pageSize);
        page.setTotal(count);
        page.setRecords(allotDepartments);
        return page;
    }

    @Override
    public Page<AllotAuthorizeVo> getAllotRoles(AllotAuthorizeVo allotAuthorizeVo, int currentPage, int pageSize) throws Exception {
        int startIndex = (currentPage - 1) * pageSize;
        Map<String, Object> queryMap = CommonUtil.packageQueryMap(allotAuthorizeVo, startIndex, pageSize);
        int count = allotAuthorizeDao.getAllotRoleCount(queryMap);
        List<AllotAuthorizeVo> allotDepartments = allotAuthorizeDao.getAllotRoles(queryMap);
        AllotAuthorizeVo authorizeVo = allotAuthorizeDao.getAuthorizeItem(allotAuthorizeVo.getAllotId(), "5");
        for (AllotAuthorizeVo model : allotDepartments) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(CommonConstant.DATE_FORMAT);
            Date date = dateFormat.parse(model.getOperateTime());
            model.setOperateTime(dateFormat.format(date));
            model.setAuthorizeId(authorizeVo.getCorrelateId());
            model.setAuthorizeItem(authorizeVo.getCorrelateName());
        }

        Page<AllotAuthorizeVo> page = new Page<>();
        page.setCurrentPage(currentPage);
        page.setPageSize(pageSize);
        page.setTotal(count);
        page.setRecords(allotDepartments);
        return page;
    }

    @Override
    public void addAllotCorrelate(String allotId, String type, String[] selectedKeys) throws Exception {
        List<AllotModel> allotModels = new ArrayList<>();
        for (String correlateId : selectedKeys) {
            Date date = new Date();
            AllotModel model = new AllotModel();
            model.setId(CommonUtil.generateUUID());
            model.setType(type);
            model.setAllotId(allotId);
            model.setCorrelateId(correlateId);
            model.setCreateTime(date);
            model.setModifiedTime(date);
            allotModels.add(model);
        }
        allotAuthorizeDao.addAllotCorrelate(allotModels);
    }

    @Override
    public AuthorizeDetailVo getAllotAuthorizeDetail(String allotId, String correlateId, String type) throws Exception {
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("allotId", allotId);
        queryMap.put("correlateId", correlateId);
        queryMap.put("type", type);

        List<AllotAuthorizeVo> authorizeVos = null;
        AllotAuthorizeVo authorizeVo = null;
        if (AllotTypeEnum.DEPARTMENT.getKey().equals(type)) {
            authorizeVos = allotAuthorizeDao.getAllotDepartments(queryMap);
        } else if (AllotTypeEnum.POST.getKey().equals(type)) {
            authorizeVos = allotAuthorizeDao.getAllotPosts(queryMap);
            authorizeVo = allotAuthorizeDao.getAuthorizeItem(allotId, "3");
        } else if (AllotTypeEnum.ROLE.getKey().equals(type)) {
            authorizeVos = allotAuthorizeDao.getAllotRoles(queryMap);
            authorizeVo = allotAuthorizeDao.getAuthorizeItem(allotId, "5");
        }
        AllotAuthorizeVo allotAuthorizeVo = authorizeVos.stream().findFirst().orElse(new AllotAuthorizeVo());

        List<MenuModel> results = null;
        if (!ObjectUtils.isEmpty(authorizeVo)) {
            Page menuPage = menuService.getAllMenu(new MenuModel(), CommonConstant.ONE, CommonConstant.MAX);
            List<MenuModel> menuList = menuPage.getRecords();
            List<MenuModel> tempMenus = new ArrayList<>();
            resolveSelectedMenu(menuList, authorizeVo.getCorrelateId(), tempMenus);
            results = tempMenus.stream().filter(obj -> ObjectUtils.isEmpty(obj.getParentId())).collect(Collectors.toList());
            TreeUtil.packageListToTree(results, tempMenus);
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat(CommonConstant.DATE_FORMAT);
        UserModel userModel = userService.getUserById(correlateId);
        AuthorizeDetailVo authorizeDetailVo = new AuthorizeDetailVo(allotAuthorizeVo, userModel);
        authorizeDetailVo.setMenuModels(results);
        authorizeDetailVo.setOperateTime(dateFormat.format(dateFormat.parse(authorizeDetailVo.getOperateTime())));
        return authorizeDetailVo;
    }

    @Override
    public void deleteAllots(String ids) throws Exception {
        List<String> list = Arrays.asList(ids.split(","));
        allotAuthorizeDao.deleteAllots(list);
    }

    private void resolveSelectedMenu(List<MenuModel> list, String selectedMenuIds, List<MenuModel> results) {
        for (MenuModel menuModel : list) {
            List<MenuModel> children = menuModel.getChildren();
            if (ObjectUtils.isEmpty(children)) {
                if (selectedMenuIds.contains(menuModel.getId())) {
                    results.add(menuModel);
                }
            } else {
                resolveSelectedMenu(children, selectedMenuIds, results);
                List<String> parentIds = results.stream().map(MenuModel::getParentId).collect(Collectors.toList());
                if (parentIds.contains(menuModel.getId())) {
                    MenuModel parent = new MenuModel();
                    BeanUtils.copyProperties(menuModel, parent);
                    parent.setChildren(null);
                    results.add(parent);
                }
            }
        }
    }
}
